﻿using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProcessMonitor
{
    /// <summary>
    /// 周期任务
    /// </summary>
    public class QuartzWork
    {
        //调度器
        static IScheduler scheduler;
        //调度器工厂
        static ISchedulerFactory factory;

        //0 0/1 * * * ?
        public async void Start()
        {
            //初始化调度器
            factory = new StdSchedulerFactory();
            scheduler = await factory.GetScheduler();
            await scheduler.Start();

            IJobDetail stockJob = JobBuilder.Create<CacheJob>().WithIdentity("stockIdentity", "group1").Build();
            ITrigger stockTrigger = TriggerBuilder.Create().WithIdentity("stockTrigger", "group1").WithCronSchedule("*/10 * * * * ?").Build();
            await scheduler.ScheduleJob(stockJob, stockTrigger);
        }
    }

    public class CacheJob : IJob
    {
        public WinProcess winpro = new WinProcess();
        public Task Execute(IJobExecutionContext context)
        {
            ProcessData.processlist.Where(p => p.IsRestart).ToList().ForEach(pro =>
            {
                Task.Run(() =>
                {
                    try
                    {
                        if (pro.IsRestart)
                        {
                            var profullname = pro.Path + Path.DirectorySeparatorChar + pro.Name.Split(' ')[0];
                            if (File.Exists(profullname))
                            {
                                var findpro = Process.GetProcessesByName(pro.Name.Split(' ')[0].Replace(".exe", "")).FirstOrDefault(p => p.MainModule.FileName == pro.Path + Path.DirectorySeparatorChar + pro.Name.Split(' ')[0]);

                                var isreboot = false;
                                var userMem = Math.Round((findpro?.PrivateMemorySize64 ?? 0) / 1024 / 1024m, 2);
                                if (findpro == null || findpro.Id == 0)
                                {
                                    #region 进程异常死亡 重启
                                    isreboot = true;
                                    winpro.SetForm(pro.Path + Path.DirectorySeparatorChar + pro.Name);

                                    Thread.Sleep(500);

                                    findpro = Process.GetProcessesByName(pro.Name.Split(' ')[0].Replace(".exe", "")).FirstOrDefault(p => p.MainModule.FileName == pro.Path + Path.DirectorySeparatorChar + pro.Name.Split(' ')[0]);
                                    #endregion
                                }
                                else
                                {
                                    bool needkill = false;

                                    #region 时间周期 增加重启判断

                                    if (!string.IsNullOrWhiteSpace(pro.RebootTimeSet))
                                    {
                                        var rebootTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " " + pro.RebootTimeSet);
                                        if (DateTime.Now > rebootTime && DateTime.Now.AddSeconds(-10) < rebootTime)
                                        {
                                            if (pro.AutoReboot == "day")
                                            {
                                                needkill = true;
                                            }
                                            else if (pro.AutoReboot.StartsWith("week"))
                                            {
                                                var weeknum = pro.AutoReboot.Split('_')[1];
                                                if (DateTime.Now.DayOfWeek.GetHashCode() == Convert.ToInt32(weeknum.Replace("星期", "")))
                                                {
                                                    needkill = true;
                                                }
                                            }
                                            else if (pro.AutoReboot.StartsWith("mouth"))
                                            {
                                                var mouthnum = pro.AutoReboot.Split('_')[1];
                                                if (DateTime.Now.Day == Convert.ToInt32(mouthnum))
                                                {
                                                    needkill = true;
                                                }
                                            }
                                        }
                                    }
                                    #endregion

                                    #region 内存判断重启
                                    if (pro.LimitMemory > 0 && pro.LimitMemory < userMem)
                                    {
                                        needkill = true;
                                    }
                                    #endregion

                                    if (needkill)
                                    {
                                        findpro.Kill();
                                        Thread.Sleep(500);
                                        isreboot = true;
                                        winpro.SetForm(pro.Path + Path.DirectorySeparatorChar + pro.Name);
                                        Thread.Sleep(500);
                                        findpro = Process.GetProcessesByName(pro.Name.Split(' ')[0].Replace(".exe", "")).FirstOrDefault(p => p.MainModule.FileName == pro.Path + Path.DirectorySeparatorChar + pro.Name.Split(' ')[0]);
                                    }
                                }
                                ProLogic.Instance.ReStartPro(pro.IndexNum, findpro.Id, 0, isreboot, pro.IsRestart, userMem);
                            }
                            else if (pro.Info != "NotFound")
                            {
                                pro.Info = "NotFound";
                                ProLogic.Instance.UpdatePro(pro.IndexNum);
                            }
                        }
                    }
                    catch
                    {
                    }
                });
            });

            return Task.CompletedTask;
        }
    }
}
